﻿using System;
using System.Web;
using OAuth.Domain;
using System.Net;

namespace OAuthTools
{
    public partial class OAuth
    {
        private readonly string _consumerKey;
        private readonly string _consumerSecret;
        private readonly string _accessToken;
        private readonly string _accessTokenSecret;
        private readonly WebProxy _proxy;

        public OAuth(string consumerKey, string consumerSecret, string accessToken = null, string accessTokenSecret = null, WebProxy proxy = null)
        {
            _consumerKey = consumerKey;
            _consumerSecret = consumerSecret;
            _accessTokenSecret = accessTokenSecret;
            _accessToken = accessToken;
            _proxy = proxy;
        }

        /// <summary>
        /// Request token is a value used by the Consumer to obtain authorization from the User, and exchanged for an Access Token.
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public Token GetRequestToken(string url)
        {
            var parameters = GetOAuthParameters(HttpMethod.Get, url, callback: "oob"); //Out of band

            var oAuthRequest = new OAuthRequest(parameters, url, HttpMethod.Get, proxy: _proxy);

            return RetrieveToken(oAuthRequest.GetResponse());
        }

        /// <summary>
        /// Access token is a value used by the Consumer to gain access to the Protected Resources on behalf of the User, instead of using the User’s Service Provider credentials.
        /// The Consumer exchanges the Request Token for an Access Token capable of accessing the Protected Resources.
        /// </summary>
        /// <param name="url"></param>
        /// <param name="requestToken"></param>
        /// <param name="requestTokenSecret"></param>
        /// <param name="verifier"></param>
        /// <returns></returns>
        public Token GetAccessToken(string url, string requestToken, string requestTokenSecret, string verifier)
        {
            var parameters = GetOAuthParameters(HttpMethod.Post, url, token: requestToken, tokenSecret: requestTokenSecret, verifier: verifier);

            var oAuthRequest = new OAuthRequest(parameters, url, HttpMethod.Post, proxy: _proxy);

            return RetrieveToken(oAuthRequest.GetResponse());
        }

        private static Token RetrieveToken(string result)
        {
            var values = HttpUtility.ParseQueryString(result);

            var tokens = new Token { Value = values.Get("oauth_token"), SecretToken = values.Get("oauth_token_secret") };

            return tokens;
        }

        /* POST Requests */
        public string PostResource(string url)
        {
            var uri = new Uri(url);
            var parameters = GetOAuthParameters(HttpMethod.Post, url, HttpUtility.ParseQueryString(uri.Query), _accessToken, _accessTokenSecret);
            url = string.Format("{0}://{1}{2}", uri.Scheme, uri.Authority, uri.AbsolutePath);
            var oAuthRequest = new OAuthRequest(parameters, url, HttpMethod.Post, proxy: _proxy);
            var queryParameters = HttpUtility.ParseQueryString(uri.Query);
            var response = oAuthRequest.GetResponse(queryParameters);

            return response;
        }
    }
}
